package com.zephyr.vchcenter.pbcFile.service.impl;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.zephyr.vchcenter.helper.HibernateSessionFactory;
import com.zephyr.vchcenter.bean.BaseObject;
import com.zephyr.vchcenter.bean.PbcOriginalData;
import com.zephyr.vchcenter.bpm.util.RandomUtil;
import com.zephyr.vchcenter.dao.IBaseDao;
//import com.zephyr.vchcenter.dao.impl.BaseDaoJbpmImpl;
import com.zephyr.vchcenter.helper.SpringHelper;
import com.zephyr.vchcenter.pbcFile.configBean.Dict;
import com.zephyr.vchcenter.pbcFile.exception.MatchException;
import com.zephyr.vchcenter.pbcFile.exception.RepeatException;
import com.zephyr.vchcenter.pbcFile.preTreat.BasePreTreator;
import com.zephyr.vchcenter.pbcFile.service.IPbcFileParseService;
import com.zephyr.vchcenter.pbcFile.util.ConfigParser;
import com.zephyr.vchcenter.pbcFile.util.FileParserUtil;
import com.zephyr.vchcenter.pbcFile.util.SingleLineParser;

/**
 * @author zhaoyunxiao
 */
public class PbcFileParseServiceImpl implements IPbcFileParseService {
	private static final Logger log = Logger
			.getLogger(PbcFileParseServiceImpl.class);
	/**
	 * @param file 人行文件
	 * @param localId 分行号
	 * @param object 与人行文件内容匹配的业务对象
	 *
	 */
	public Map<String, Object> parseFile(File file, String localId,
			BaseObject object) {
		log.debug("enter:PbcFileParseServiceImpl:parseFile ");
		Map<String,Object> returnMap=new HashMap<String, Object>();
		List<BaseObject> returnValue = null;
		try {
			log.debug("enter:PbcFileParseServiceImpl:parseFile:parseConfig");
			//加载解析器配置信息ݴ���ķ��кŽ��������ļ�
			ConfigParser configParser = new ConfigParser();
			Dict dict = configParser.parseConfig(localId);
			dict.setFile(file);
			//根据配置文件的配置取得相应的解析器Ԥ���������Ԥ����
			List<String> list = new ArrayList<String>();
			BasePreTreator basePreTreator = (BasePreTreator) Class.forName(
					dict.getSource()).newInstance();
			//得到单行格式Ԥ�������б�
			list = basePreTreator.preTreat(dict);
			log.debug("enter:PbcFileParseServiceImpl:parseFile:singleLineParse");
			
			returnValue = new ArrayList<BaseObject>();
			//用来装载为解析成功的数据的集合
			List<Object> noParseList = new ArrayList<Object>();
			//调用单行解析器根据配置信息对单行文件进行解析Ԥ�����Ľ����д���
			SingleLineParser singleLineParser = new SingleLineParser();
			for (String str : list) {
				Map<String, Object> map = singleLineParser.parse(str, dict
						.getProperties(), dict.getRegex(), object,dict.getShenzhenFile());
				//ݿ�
				if (map != null) {
					PbcOriginalData pbcOriginalData = new PbcOriginalData();
					pbcOriginalData.setSource(str);
					//获得解析失败信息ܵ����
					if (map.get("noParse") != null) {
						noParseList.add(map.get("noParse"));
					}else{
						//利用反射的方式将解析出来的人行数据与业务对象匹配
						BaseObject baseObject = FileParserUtil.encapsulation(
								pbcOriginalData, map);
						PbcOriginalData pbcOriginalDataTemp = (PbcOriginalData) baseObject;
						pbcOriginalDataTemp.setSubno(((PbcOriginalData) object)
								.getSubno());
						pbcOriginalDataTemp.setVchdate(((PbcOriginalData) object)
								.getVchdate());
						pbcOriginalDataTemp.setVcsession(((PbcOriginalData) object)
								.getVcsession());
						//设置解析状态
					pbcOriginalDataTemp.setState(1);
					returnValue.add(pbcOriginalDataTemp);
					}
					
				}
			}
		     //List objectTemp = null;��ļ����ж�
			Long countTemp=null;
			if (returnValue != null && returnValue.size() > 0) {
				PbcOriginalData pbcOriginalData = (PbcOriginalData) returnValue
						.get(0);
				PbcOriginalData pbcOriginalDataTemp = new PbcOriginalData();
				pbcOriginalDataTemp.setSubno(pbcOriginalData.getSubno());
				pbcOriginalDataTemp.setVchdate(pbcOriginalData.getVchdate());
				pbcOriginalDataTemp
						.setVcsession(pbcOriginalData.getVcsession());
				countTemp=getFirstCount(pbcOriginalDataTemp);
				log.debug(countTemp+"##############");
			}
			returnMap.put("successfulData", returnValue);
			log.debug(returnValue.size()+"------------------------------------------>");
			returnMap.put("failData", noParseList);
			log.debug(noParseList.size());
			returnMap.put("totalNum", list.size());
			log.debug(list.size());
			if (returnValue.size() == 0) {
				throw new MatchException();
			}
			//������
			//����
			//if (objectTemp != null&&objectTemp.size()>0) {
			if(countTemp!=null&&countTemp>0 ){
				log.debug("okok");
				log.debug(returnValue.get(1).toString());
				PbcOriginalData pd=new PbcOriginalData();
				
				for (Object obj : returnValue) {
					Long count = getCount((PbcOriginalData)obj);
					if (count != null && count > 0) {
						throw new RepeatException("文件重复!");
					}
					/*Date d3 = new Date();
					List tempList=listObjectByProperties((PbcOriginalData) obj);
					Date d4 = new Date();
					System.out.println(d4.getTime()-d3.getTime()+"......+..._..+.......");
					if(tempList!=null&&tempList.size()>0){
						throw new RepeatException(" �ļ��ظ�����ȷ�ϣ�");
					}*/
				}
			}
			//ݿ�
			if (noParseList.size() > 0) {
				RandomUtil randomUtil=new RandomUtil();
				
				for (Object obj : noParseList) {

					PbcOriginalData pbcOriginalData=(PbcOriginalData) obj;
					pbcOriginalData.setPbcsid(randomUtil.getUUID());
					persistOneObject(pbcOriginalData);
				}
			}
		} catch (InstantiationException e) {
			log.error("PbcFilePaseServiceImpl", e);
		} catch (IllegalAccessException e) {
			log.error("PbcFilePaseServiceImpl", e);
		} catch (ClassNotFoundException e) {
			log.error("PbcFilePaseServiceImpl", e);
		}
		

		return returnMap;
	}
   
	//持久化解析成功的数据
	public void persistSuccessful(List<BaseObject> list) {
		log.debug("begin persist...........");
		RandomUtil randomUtil=new RandomUtil();
		Session session = HibernateSessionFactory.getSession();
		//IBaseDao dao=(IBaseDao)SpringHelper.getBean("baseDao");
		Transaction transaction = session.beginTransaction();
		
		for (BaseObject baseObject : list) {
			//dao.saveOrUpdate((PbcOriginalData) baseObject);
			PbcOriginalData pbcOriginalData=(PbcOriginalData) baseObject;
			pbcOriginalData.setPbcsid(randomUtil.getUUID());
			session.saveOrUpdate(pbcOriginalData);
		}
		transaction.commit();

	}
	//根据解析状态查询数据
	public List<PbcOriginalData> listPbcData(Integer state) {

		//Session session = HibernateSessionFactory.getSession();
		IBaseDao dao=(IBaseDao)SpringHelper.getBean("baseDao");
		PbcOriginalData pbcOriginalData = new PbcOriginalData();
		pbcOriginalData.setState(state);
		List<Object> list = dao.findByExample(pbcOriginalData);
		List<PbcOriginalData> temp = new ArrayList<PbcOriginalData>();
		for (Object obj : list) {
			temp.add((PbcOriginalData) obj);
		}
		return temp;
	}

	//根据分行号查询解析器配置信息
	public Dict getDictInfoBySubno(String subno) {
		Dict dict = new ConfigParser().parseConfig(subno);
		return dict;
	}

	//通过id获得对象
	public Object getObject(Class clazz, Serializable id) {
		//Session session = HibernateSessionFactory.getSession();
		//Transaction transaction = session.beginTransaction();
		IBaseDao dao=(IBaseDao)SpringHelper.getBean("baseDao");
		Object object = dao.findById(clazz.getName(), id.toString());//session.get(clazz, id);
		//transaction.commit();
		return object;
	}

	//持久化单个对象
	public void persistOneObject(Object object) {
		//Session session = HibernateSessionFactory.getSession();
		IBaseDao dao=(IBaseDao)SpringHelper.getBean("baseDao");
		//Transaction transaction = session.beginTransaction();
		dao.saveOrUpdate(object);
		//transaction.commit();

	}
	//通过条件查询
	public List<Object> listObjectByProperties(Object object) {
		//Session session = HibernateSessionFactory.getSession();
		IBaseDao dao=(IBaseDao)SpringHelper.getBean("baseDao");
		//System.out.println(session.hashCode()+"hh");
		//Transaction transaction = session.beginTransaction();
		List<Object> list = dao.findByExample(object);
		//transaction.commit();
		return list;
	}

	//根据分行号 场次 日期 帐号 金额 人行流水号得到相应数据的条数
	private Long getCount(PbcOriginalData pbcOriginalData) {
		Session session = HibernateSessionFactory.getSession();
		String subnoTemp = pbcOriginalData.getSubno();
		String accnoTemp = pbcOriginalData.getAccno();
		String vcsessionTemp = pbcOriginalData.getVcsession();
		String vchdateTemp = pbcOriginalData.getVchdate();
		String amountTemp = pbcOriginalData.getAmount();
		String msidTemp = pbcOriginalData.getMsid();
		StringBuffer stbHql=new StringBuffer("select count(*) from PbcOriginalData as p where p.subno=:subnoTemp and p.vcsession=:vcsessionTemp"
				+ " and p.vchdate=:vchdateTemp");
		String hql = "select count(*) from PbcOriginalData as p where p.subno=:subnoTemp and p.accno=:accnoTemp and p.vcsession=:vcsessionTemp"
				+ " and p.vchdate=:vchdateTemp and p.amount=:amountTemp and p.msid=:msidTemp";
		if(accnoTemp!=null&&accnoTemp.length()>0){
			stbHql.append(" and p.accno=:accnoTemp");
		}if(amountTemp!=null&&amountTemp.length()>0){
			stbHql.append(" and p.amount=:amountTemp");
		}if(msidTemp!=null&&msidTemp.length()>0){
			stbHql.append(" and p.msid=:msidTemp");
		}
		Query query = session.createQuery(stbHql.toString());
		query.setString("subnoTemp", subnoTemp);
		query.setString("vcsessionTemp", vcsessionTemp);
		query.setString("vchdateTemp", vchdateTemp);
		if(accnoTemp!=null&&accnoTemp.length()>0){
			query.setString("accnoTemp", accnoTemp);
		}if(amountTemp!=null&&amountTemp.length()>0){
			query.setString("amountTemp", amountTemp);
		}if(msidTemp!=null&&msidTemp.length()>0){
			query.setString("msidTemp", msidTemp);
		}
		return (Long) query.uniqueResult();
	}
	//根据分行号 场次 日期 得到相应数据的数量���ݵ�����
	private Long getFirstCount(PbcOriginalData pbcOriginalData){
		Session session = HibernateSessionFactory.getSession();
		String subnoTemp = pbcOriginalData.getSubno();
		String vcsessionTemp = pbcOriginalData.getVcsession();
		String vchdateTemp = pbcOriginalData.getVchdate();
		String hql="select count(*) from PbcOriginalData as p where p.subno=:subnoTemp  and p.vcsession=:vcsessionTemp  and p.vchdate=:vchdateTemp";
		Query query = session.createQuery(hql);
		query.setString("subnoTemp", subnoTemp);
		query.setString("vcsessionTemp", vcsessionTemp);
		query.setString("vchdateTemp", vchdateTemp);
		return (Long) query.uniqueResult();
	}

	//
	public Object getObjectByProperties(Object object) {
		/*Session session = HibernateSessionFactory.getSession();
		IBaseDao dao = new BaseDaoJbpmImpl(session);
		Transaction transaction = session.beginTransaction();
		Object obj = dao.findOneByExample(object);
		transaction.commit();
		return obj;
		IBaseDao dao=(IBaseDao)SpringHelper.getBean("baseDao");
		List results=dao.findByExample(object);
		if(results.size()>0){	
		}*/
		return null;
	}
	

}
